package com.ow.dva.config.shiro;

import com.ow.dva.module.account.entity.Account;
import com.ow.dva.module.account.entity.AccountInfo;
import com.ow.dva.module.account.service.AccountInfoService;
import com.ow.dva.module.account.service.AccountService;
import com.ow.dva.module.permission.service.PermissionService;
import com.ow.dva.module.permission.service.RoleService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author GaoXiang
 * @version 1.0
 * @since 2016/10/28.
 */
public class AdminDbRealm extends AuthorizingRealm {

    @Resource
    private RoleService roleService;

    @Resource
    private AccountService accountService;

    @Resource
    private AccountInfoService accountInfoService;

    @Resource
    private PermissionService permissionService;

    Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 权限信息
     * @param authenticationToken Token
     * @return 认证
     * @throws AuthenticationException 认证失败
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken){
        logger.debug("开始认证权限...");

        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        Account account = accountService.findByUserName(token.getUsername());

        //没有此用户
        if (account == null)
            throw new UnknownAccountException();

        // 密码错误
        if (!account.getPassword().equals(new String(token.getPassword())))
            throw new IncorrectCredentialsException();

        //身份没有被授权登陆后台
        if (!account.getType().contains("admin"))
            throw new AuthenticationException();

        //账户被禁止登录
        if(account.getStatus() < 0)
            throw new LockedAccountException();

        //获取用户详细信息
        AccountInfo accountInfo = accountInfoService.findByAccountId(account.getId());
        ShiroAccount shiroAccount = new ShiroAccount(account.getId(), account.getUserName(),account,accountInfo);

        //返回认证信息由父类AuthenticatingRealm进行认证
        return new DvaAuthenticationInfo(shiroAccount, account.getPassword(), getName());
    }


    /**
     * 授权
     * @param principalCollection 会话信息
     * @return 认证结果
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        //获取登陆用户信息
        ShiroAccount shiroAccount = (ShiroAccount) principalCollection.getPrimaryPrincipal();
        logger.debug("授权中..." + " 用户名：" + shiroAccount.getUserName());
        logger.debug("授权中..." + " ID：" + shiroAccount.getId());

        //创建权限和角色容器
        List<String> permissions = new ArrayList<>(),roles = new ArrayList<>();

        //绑定、判断用户所有角色和权限
        roleService.selectByAccountId(shiroAccount.getId()).forEach(role -> {
            if(!StringUtils.isEmpty(role.getShiro())){roles.add(role.getShiro());}
            permissionService.selectByRoleId(role.getId()).forEach(power -> {
                if(!StringUtils.isEmpty(power.getShiro())){permissions.add(power.getShiro());}
            });
        });

        logger.debug("全部角色：" + roles);
        logger.debug("全部权限：" + permissions);
        //返回权限信息
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roles);
        info.addStringPermissions(permissions);
        return info;
    }

}
